package jeconbond.experiment.market.resourcerelations.generate;

import jeconbond.economic.IEconomicEngine;
import jeconbond.economic.agent.IEconomicProducer;
import jeconbond.economic.market.agent.service.SpySellsAgent;
import jeconbond.economic.market.agent.service.ResellResourceExpensiveSpeculantAgent;
import jeconbond.economic.agent.ActIFFinRangeOfStepsAgent;
import jeconbond.economic.resources.IResourceType;
import jeconbond.experiment.market.resourcerelations.process.IResourceRelationExperimentContext;
import jeconbond.experiment.market.resourcerelations.ResourceRelationExperimentSettings;
import jeconbond.experiment.market.equilibrium.generate.MooreEngineInitialiser;
import jeconbond.automata.behaviour.antstrat.IFeramonStorrage;
import jeconbond.experiment.generate.IEngineInitialiser;
import laboratoryQ.experiment.process.IExperimentContext;

public class BrosnenEngineInitialiser implements IEngineInitialiser {
	private MooreEngineInitialiser mooreInitialiser = 
		new MooreEngineInitialiser();

	@Override
	public void initialise(
			IEconomicEngine engine, 
			IEconomicProducer[] agents, 
			IExperimentContext iexperimentContext
	) {
		mooreInitialiser.initialise(engine, agents, iexperimentContext);
		IResourceRelationExperimentContext experimentContext =
			(IResourceRelationExperimentContext) iexperimentContext;
		addSpeculant(engine, experimentContext);
		addAnts(engine, experimentContext);
	}

	private void addSpeculantAgent(
			IEconomicEngine engine,
			IResourceRelationExperimentContext experimentContext,
			SpySellsAgent spySellsAgent
	) {
		ResourceRelationExperimentSettings settings = 
			experimentContext.getExperimentSettings();
		int goalResourcePos = Math.min(
				settings.resources.length,
				settings.goalResourceIndex
		);
		IResourceType speculantGoal = settings.resources[goalResourcePos];
		IEconomicProducer speculant = new ResellResourceExpensiveSpeculantAgent(
				speculantGoal,
				experimentContext.getRRS(),
				settings.speculantPropCountMarketPart,
				settings.speculantGoalValueMarketPart
		);
		spySellsAgent.addIgnoreBuyer(speculant);
		ActIFFinRangeOfStepsAgent.PreService speculantDecorator = new ActIFFinRangeOfStepsAgent.PreService(
				speculant,
				experimentContext.getNextStepCommander().stepCounter,
				settings.timeStepX,
				Integer.MAX_VALUE
		);
		engine.addAgents(speculantDecorator);
	}

	private void addAnts(
			IEconomicEngine engine,
			IResourceRelationExperimentContext experimentContext
	) {
		ResourceRelationExperimentSettings settings = experimentContext.getExperimentSettings();
		for (IFeramonStorrage feramonStorrage : experimentContext.getFeramonStorragesList()) {
			engine.addAgents(
					feramonStorrage.generateAntAgents(
							settings.antAgentCount, 
							experimentContext.getRRS()
					)
			);
		}
	}

	private void addSpeculant(
			IEconomicEngine engine,
			IResourceRelationExperimentContext experimentContext
	) {
		if (experimentContext.getExperimentSettings().timeStepX > -1) {
			addSpeculantAgent(engine, experimentContext, experimentContext.getSpySellsAgent());
		}
	}
}
